const fp = require('lodash')
const fs = require('fs')
class IO {
  static of (value) {
    return new IO(function () {
      return value
    })
  }

  constructor (fn) {
    this._value = fn
  }

  map (fn) {
    return new IO(fp.flowRight(fn, this._value))
  }

  join () {
    return this._value()
  }

  // 当fn返回一个函子的时候，用flatMap拍平
  flatMap (fn) {
    return this.map(fn).join()
  }
}

const readFile = function (filename) {
  return new IO(function () {
    return fs.readFileSync(filename, 'utf-8')
  })
}

const print = function (x) {
  return new IO(function () {
    console.log(x)
    return x
  })
}

// const cat = fp.flowRight(print, readFile)
// // IO(IO(x))
// // const r = cat('package.json')._value() // IO { _value: [Function (anonymous)] }
// const r = cat('package.json')._value()._value()

const r = readFile('package.json')
.map(fp.toUpper)
.flatMap(print)
.join()

console.log(r)